/*
 * ﻿Copyright (C) 2013-2014 NewMain Softech
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.newmainsoftech.eatestutil.container;

import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import javax.naming.NamingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Abstract implementation of <code>{@link EjbContainerMate}</code> and 
 * <code>{@link EjbContextCloseHandler}</code>.<br />
 * 
 * @author Arata Y.
 */
public abstract class AbstractEjbContainerMateImpl implements EjbContainerMate, EjbContextCloseHandler {
	private Logger logger = LoggerFactory.getLogger( this.getClass());
		protected Logger getLogger() {
			return logger;
		}
		protected void setLogger( final Logger logger) {
			this.logger = logger;
		}
		
	private EJBContainer ejbContainer;
		/**
		 * {@inheritDoc}
		 */
		@Override
		public EJBContainer getEjbContainer() {
			return ejbContainer;
		}
		/**
		 * {@inheritDoc}
		 */
		@Override
		public void setEjbContainer( final EJBContainer ejbContainer) {
			getCloseHandler().setEjbContainer( ejbContainer);
			this.ejbContainer = ejbContainer;
		}
	private Context context;
		/**
		 * {@inheritDoc}
		 */
		@Override
		public Context getContext() {
			return context;
		}
		/**
		 * {@inheritDoc}
		 */
		@Override
		public void setContext( final Context context) {
			getCloseHandler().setContext( context);
			this.context = context;
		}
		
	private ContainerConfig containerConfig;
		/**
		 * {@inheritDoc}
		 */
		@Override
		public ContainerConfig getContainerConfig() {
			return containerConfig;
		}
		public void setContainerConfig( final ContainerConfig containerConfig) {
			this.containerConfig = containerConfig;
		}
		
	/**
	 * {@inheritDoc}
	 */
	@Override
	@SuppressWarnings( value = { "unchecked"})
	public <T> T contextLookup( Class<T> type) throws NamingException {
		return (T)(getContext()
				.lookup( "java:global/".concat( getEjbModuleName())
						.concat( "/").concat( type.getSimpleName())));
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	@SuppressWarnings( value = { "unchecked"})
	public <T> T contextLookup( Class<?> implClass, Class<T> interfaceClass) throws NamingException {
		implClass.asSubclass( interfaceClass);
		
		final String subJndiPathToTargetType
		= implClass.getSimpleName().concat( "!").concat( interfaceClass.getName());
		return (T)(getContext()
				.lookup( "java:global/".concat( getEjbModuleName())
						.concat( "/").concat( subJndiPathToTargetType)));
	}
	
	// for closing EJB context and EJB container -------------------------------------------------- 
	private EjbContextCloseHandlerImpl closeHandler = new EjbContextCloseHandlerImpl( this);
		public EjbContextCloseHandlerImpl getCloseHandler() {
			if ( ( closeHandler.getEjbModuleName() == null) && ( getEjbModuleName() != null)) {
				closeHandler.setEjbModuleName( getEjbModuleName());
			}
			return closeHandler;
		}
		public void setCloseHandler( final EjbContextCloseHandlerImpl closeHandler) {
			this.closeHandler = closeHandler;
		}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void registerConsumer( final Object consumer) {
		getCloseHandler().registerConsumer( consumer);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeConsumer( final Object consumer) {
		getCloseHandler().removeConsumer( consumer);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getConsumerCount() {
		return getCloseHandler().getConsumerCount();
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isContainerClosedToo() {
		return getCloseHandler().isContainerClosedToo();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setContainerClosedToo( boolean isContainerClosedToo) {
		getCloseHandler().setContainerClosedToo( isContainerClosedToo);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isClosedByNonConsumer() {
		return getCloseHandler().isClosedByNonConsumer();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setClosedByNonConsumer( boolean isClosedByNonConsumer) {
		getCloseHandler().setClosedByNonConsumer( isClosedByNonConsumer);
	}
	
	protected long getCloseLockAcquireTimeOut() {
		return getCloseHandler().getCloseLockAcquireTimeOut();
	}
	protected void setCloseLockAcquireTimeOut( long closeLockAcquireTimeOut) {
		getCloseHandler().setCloseLockAcquireTimeOut( closeLockAcquireTimeOut);
	}
			
	/**
	 * {@inheritDoc}
	 */
	@Override
	public long getCloseDelay() {
		return getCloseHandler().getCloseDelay();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setCloseDelay( long closeDelay) {
		getCloseHandler().setCloseDelay( closeDelay);
	}
		
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void close() {
		getCloseHandler().close();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void cancelClose() {
		getCloseHandler().cancelClose();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean hasBeenClosed() {
		return getCloseHandler().hasBeenClosed();
	}
	// --------------------------------------------------------------------------------------------
}
